package com.zdw.oauth.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zdw.common.exception.GlobalException;
import com.zdw.oauth.config.international.InternationalUtils;
import com.zdw.oauth.dto.RoleAddDto;
import com.zdw.oauth.dto.RoleSelectDto;
import com.zdw.oauth.dto.RoleUpdDto;
import com.zdw.oauth.dto.UserRoleDto;
import com.zdw.oauth.entity.RoleEntity;
import com.zdw.oauth.entity.RolePermissionEntity;
import com.zdw.oauth.entity.UserRoleEntity;
import com.zdw.oauth.mapper.RoleMapper;
import com.zdw.oauth.mapper.RolePermissionMapper;
import com.zdw.oauth.mapper.UserRoleMapper;
import com.zdw.oauth.service.RoleService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色 服务实现类
 * </p>
 *
 * @author 卓德文
 * @since 2023-07-17
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, RoleEntity> implements RoleService {

    @Resource
    private UserRoleMapper userRoleMapper;

    @Resource
    private RolePermissionMapper rolePermissionMapper;

    /**
     * 新增角色
     *
     * @param dto
     * @return
     */
    @Override
    public boolean add(RoleAddDto dto) {
        //1.根据角色额编码或角色名称查询角色
        RoleEntity entity = this.selectByCodeOrName(dto.getCode(), dto.getName(), null);
        if (ObjectUtil.isNotEmpty(entity) && StrUtil.isNotBlank(entity.getCode())) {
            throw new GlobalException(InternationalUtils.getInternational("role.exist"));
        }

        //2.新增
        RoleEntity roleEntity = BeanUtil.copyProperties(dto, RoleEntity.class);
        Integer loginId = Integer.parseInt(StpUtil.getTokenInfo().getLoginId().toString());
        Date date = new Date();
        roleEntity.setCreator(loginId);
        roleEntity.setModifier(loginId);
        roleEntity.setCreateTime(date);
        roleEntity.setUpdateTime(date);
        return this.baseMapper.insert(roleEntity) > 0;
    }

    /**
     * 编辑角色
     *
     * @param dto
     * @return
     */
    @Override
    public boolean update(RoleUpdDto dto) {
        //1.根据角色额编码或角色名称查询角色
        RoleEntity entity = this.selectByCodeOrName(dto.getCode(), dto.getName(), dto.getId());
        if (ObjectUtil.isNotEmpty(entity) && StrUtil.isNotBlank(entity.getCode())) {
            throw new GlobalException(InternationalUtils.getInternational("role.exist"));
        }

        //2.编辑
        RoleEntity roleEntity = BeanUtil.copyProperties(dto, RoleEntity.class);
        roleEntity.setModifier(Integer.parseInt(StpUtil.getTokenInfo().getLoginId().toString()));
        roleEntity.setUpdateTime(new Date());
        return this.baseMapper.updateById(roleEntity) > 0;
    }

    /**
     * 删除角色(批量)
     *
     * @param roleIdList
     * @return
     */
    @Override
    public boolean delete(List<Integer> roleIdList) {
        //1.删除角色
        Wrapper<RoleEntity> roleWrapper = Wrappers.lambdaQuery(RoleEntity.class).in(RoleEntity::getId, roleIdList);
        int delCount = this.baseMapper.delete(roleWrapper);

        if (delCount > 0) {
            //2.删除用户-角色的关联关系
            Wrapper<UserRoleEntity> userRoleWrapper = Wrappers.lambdaQuery(UserRoleEntity.class)
                    .in(UserRoleEntity::getRoleId, roleIdList);
            userRoleMapper.delete(userRoleWrapper);

            //3.删除角色-权限的关联关系
            Wrapper<RolePermissionEntity> RolePermissionWrapper = Wrappers.lambdaQuery(RolePermissionEntity.class)
                    .in(RolePermissionEntity::getRoleId, roleIdList);
            rolePermissionMapper.delete(RolePermissionWrapper);

            //3.删除子角色--暂不删除
            //4.删除子角色-权限的关联关系--暂不删除
            //5.删除子角色-用户的关联关系--暂不删除
        }
        return delCount > 0;
    }

    /**
     * 查询角色信息
     *
     * @param id
     * @return
     */
    @Override
    public RoleEntity select(int id) {
        return this.baseMapper.selectById(id);
    }

    /**
     * 分页查询角色列表
     *
     * @param dto
     * @return
     */
    @Override
    public IPage<RoleEntity> page(RoleSelectDto dto) {
        IPage<RoleEntity> page = new Page<>(dto.getPageNum(), dto.getPageSize());
        Wrapper<RoleEntity> wrapper = Wrappers.lambdaQuery(RoleEntity.class)
                .eq(StrUtil.isNotBlank(dto.getCode()), RoleEntity::getCode, dto.getCode())
                .like(StrUtil.isNotBlank(dto.getName()), RoleEntity::getName, dto.getName())
                .eq(ObjectUtil.isNotNull(dto.getParentId()), RoleEntity::getParentId, dto.getParentId())
                .eq(ObjectUtil.isNotNull(dto.getState()), RoleEntity::getState, dto.getState());
        return this.baseMapper.selectPage(page, wrapper);
    }

    /**
     * 查询角色树
     *
     * @return
     */
    @Override
    public List<RoleEntity> tree() {
        return this.baseMapper.tree();
    }

    /**
     * 给用户分配角色
     *
     * @param dto
     * @return
     */
    @Override
    public Boolean grantRole(UserRoleDto dto) {
        int loginId = Integer.parseInt(StpUtil.getTokenInfo().getLoginId().toString());

        //1.查询传参进来的所有角色下的所有子角色
        List<RoleEntity> roleList = this.baseMapper.selectSonListByIdList(dto.getRoleIdList());

        //2.角色集合去重,并取出其中的ID集合
        List<Integer> idList = roleList.stream().map(x -> x.getId()).distinct().collect(Collectors.toList());

        //3.所有角色ID集合=上级角色ID集合+子角色ID集合
        List<Integer> collectList = dto.getRoleIdList().stream().distinct().collect(Collectors.toList());
        collectList.addAll(idList);

        //4.先删除用户之前的"用户-角色"关联关系
        int deleteCount = userRoleMapper.deleteUserRoleByUserId(dto.getUserId());

        //5.批量新增"用户-角色"关联关系
        if (deleteCount > 0) {
            return userRoleMapper.saveUserRoleList(dto.getUserId(), loginId, collectList) > 0;
        }

        return deleteCount > 0;
    }

    /**
     * 根据角色编码或角色名称查询角色
     *
     * @return
     */
    private RoleEntity selectByCodeOrName(String code, String name, Integer id) {
        LambdaQueryWrapper<RoleEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(StrUtil.isNotBlank(code), RoleEntity::getCode, code)
                .or()
                .eq(StrUtil.isNotBlank(name), RoleEntity::getName, name)
                .ne(ObjectUtil.isNotEmpty(id), RoleEntity::getId, id)
                .last(" limit 1");
        return this.baseMapper.selectOne(queryWrapper);
    }

}
